﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Utilities
{
    public class Encryption
    {
        // This constant string is used as a "salt" value for the PasswordDeriveBytes function calls.
        // This size of the IV (in bytes) must = (keysize / 8).  Default keysize is 256, so the IV must be
        // 32 bytes long.  Using a 16 character string here gives us 32 bytes when converted to a byte array.
        private static readonly byte[] initVectorBytes = Encoding.ASCII.GetBytes("tu89geji340t89u2");

        // This constant is used to determine the keysize of the encryption algorithm.
        private const int keysize = 256;

        public static string Encrypt(string plainText, string passPhrase)
        {
            byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
            using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
            {
                byte[] keyBytes = password.GetBytes(keysize / 8);
                using (RijndaelManaged symmetricKey = new RijndaelManaged())
                {
                    symmetricKey.Mode = CipherMode.CBC;
                    using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes))
                    {
                        using (MemoryStream memoryStream = new MemoryStream())
                        {
                            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                            {
                                cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                                cryptoStream.FlushFinalBlock();
                                byte[] cipherTextBytes = memoryStream.ToArray();
                                return Convert.ToBase64String(cipherTextBytes);
                            }
                        }
                    }
                }
            }
        }

        public static string Decrypt(string cipherText, string passPhrase)
        {
            byte[] cipherTextBytes = Convert.FromBase64String(cipherText);
            using (PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, null))
            {
                byte[] keyBytes = password.GetBytes(keysize / 8);
                using (RijndaelManaged symmetricKey = new RijndaelManaged())
                {
                    symmetricKey.Mode = CipherMode.CBC;
                    using (ICryptoTransform decryptor = symmetricKey.CreateDecryptor(keyBytes, initVectorBytes))
                    {
                        using (MemoryStream memoryStream = new MemoryStream(cipherTextBytes))
                        {
                            using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                            {
                                byte[] plainTextBytes = new byte[cipherTextBytes.Length];
                                int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
                                return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
                            }
                        }
                    }
                }
            }
        }

        public static void EncryptConnectionString(bool encrypt, string fileName)
        {
            string errorMessage = "mz\n";
            Configuration configuration = null;
            try
            {
                errorMessage += "Openingfile\n";
                // Open the configuration file and retrieve the connectionStrings section.
                configuration = ConfigurationManager.OpenExeConfiguration(fileName);
                errorMessage += "Getting config section\n";
                try
                {
                    ConnectionStringsSection configSection =
                            configuration.GetSection("connectionStrings") as ConnectionStringsSection;
                    if ((!(configSection.ElementInformation.IsLocked)) &&
                        (!(configSection.SectionInformation.IsLocked)))
                    {
                        errorMessage = "Inside first if\n";
                        if (encrypt && !configSection.SectionInformation.IsProtected)
                        {
                            errorMessage += "2nd If\n";
                            //this line will encrypt the file
                            configSection.SectionInformation.ProtectSection
                                ("DataProtectionConfigurationProvider");
                        }

                        if (!encrypt &&
                        configSection.SectionInformation.IsProtected)//encrypt is true so encrypt
                        {
                            errorMessage = "3rd If\n";
                            //this line will decrypt the file. 
                            configSection.SectionInformation.UnprotectSection();
                        }
                        errorMessage += "configSection.SectionInformation.ForceSave = true\n";
                        //re-save the configuration file section
                        configSection.SectionInformation.ForceSave = true;
                        // Save the current configuration

                        errorMessage += "configuration.Save();\n";
                        configuration.Save();
                        //Process.Start("notepad.exe", configuration.FilePath);
                    }
                }
                catch (Exception)
                {
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(errorMessage, "Data Protection Configuration Provider", MessageBoxButtons.OK, MessageBoxIcon.Error);
                MessageBox.Show(ex.ToString());
            }
        }
    }
}
